package com.sdy.resdir.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.approval.api.ApprovalAllApi;
import com.sdy.auth.api.model.UserInfo;
import com.sdy.auth.client.service.SsoService;
import com.sdy.common.model.BizException;
import com.sdy.common.model.Response;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.StringUtil;
import com.sdy.dcsb.api.DcsbApi;
import com.sdy.resdir.biz.model.*;
import com.sdy.resdir.biz.service.*;
import com.sdy.usercenter.api.UserQueryApi;
import com.sdy.usercenter.api.dto.UserDTO;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.sdy.mvc.controller.BaseController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 实施工单 前端控制器
 * </p>
 *
 * @author hyh
 * @since 2019-10-21
 */
@Slf4j
@RestController
@SuppressWarnings("unchecked")
@Api(tags = "实施工单")
@RequestMapping("/rdImplementationOrder")
public class RdImplementationOrderController extends BaseController {
    @Autowired
    private RdImplementationOrderService rdImplementationOrderService;
    @Autowired
    private RdResourceDirService rdResourceDirService;
    @Autowired
    private ApprovalAllApi approvalAllApi;
    @Autowired
    private SsoService ssoService;
    @Autowired
    UserQueryApi userQueryApi;
    @Autowired
    RdResDetailsApiService rdResDetailsApiService;
    @Autowired
    RdResourceDirDataService resourceDirDataService;
    @Autowired
    RdResourceApplicationDetailService rdResourceApplicationDetailService;
    @Autowired
    RdResForOnlineService rdResForOnlineService;
    @Autowired
    private RdResDataItemService rdResDataItemService;
    @Autowired
    private RdOrderAppService rdOrderAppService;

    @ApiOperation("未上线资源实施工单页面")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "资源类型: (1.服务接口类 2.服务页面类 3.数据教换类)"),
            @ApiImplicitParam(name = "resName", value = "资源名称:模糊查询")
    })
    @GetMapping("/implOrderList")
    public Response implOrderPageList(Page page, Integer type, String resName, HttpServletRequest request) throws Exception {
        Integer userId = ssoService.getUserId(request);
        Assert.isNull(userId, "用户未登录");
        UserDTO user = userQueryApi.getUser(userId);
        resName = URLDecoder.decode(resName, "UTF-8");
        IPage<RdImplementationOrder> ordersAndApplications = null;
        ordersAndApplications = rdImplementationOrderService.page(page, Wrappers.<RdImplementationOrder>lambdaQuery()
                .eq(null != type, RdImplementationOrder::getResType, type)
                .eq(RdImplementationOrder::getOrderType, 2)
                .eq(RdImplementationOrder::getDeptId, user.getOwnDeptId())
                .like(StringUtil.isNotEmpty(resName) && StringUtil.isNotBlank(resName), RdImplementationOrder::getResName, resName)
                .orderByDesc(RdImplementationOrder::getId));
        //存放实施工单对应的资源申请单详情
        if (!ordersAndApplications.getRecords().isEmpty()) {
            List<Integer> resIds = ordersAndApplications.getRecords().stream().map(RdImplementationOrder::getResId).collect(Collectors.toList());
            List<String> applyNums = ordersAndApplications.getRecords().stream().map(RdImplementationOrder::getApplyNum).collect(Collectors.toList());
            List<RdResForOnline> rdResForOnlineList = rdResForOnlineService.list(new LambdaQueryWrapper<RdResForOnline>()
                    .in(RdResForOnline::getResId, resIds)
                    .in(RdResForOnline::getApplicationNum, applyNums));
            for (int i = 0; i < ordersAndApplications.getRecords().size(); i++) {
                Integer resId = resIds.get(i);
                Assert.isNull(resId, "无法获取资源id");
                String applyNum = applyNums.get(i);
                Assert.isNull(applyNum, "无法获取订单号");
                for (RdResForOnline rdResForOnline : rdResForOnlineList) {
                    if (rdResForOnline.getResId().equals(resId) && rdResForOnline.getApplicationNum().equals(applyNum)) {
                        ordersAndApplications.getRecords().get(i).setRdResForOnline(rdResForOnline);
                    }
                }
            }
        }
        return Response.success(ordersAndApplications);
    }

    @ApiOperation(value = "实施工单状态操作")
    @PostMapping("/changeNotOnlineResourceImpOrderState")
    public Response changeNotOnlineResourceImpOrderState(@RequestBody @ApiParam(name = "id,orderOperate,cancelReason,resType", value = "实施工单号，操作类型（0 实施中 1 实施完成 2 取消实施）,取消实施理由,资源类型") Map<String, Object> map, HttpServletRequest request) throws
            BizException {
        UserInfo userInfo = ssoService.getUserInfo(request);
        Assert.isNull(userInfo, "用户未登录");
        Date date = new Date();
        Integer userId = userInfo.getUserId();
        String userName = userInfo.getUserName();
        Integer id = (Integer) map.get("id");
        Assert.isNull(id, "id不可为空");
        Integer postResType = (Integer) map.get("resType");
        Integer orderOperate = (Integer) map.get("orderOperate");
        Assert.isNull(orderOperate, "请选择实施工单操作类型");
        RdImplementationOrder rdImplementationOrder = rdImplementationOrderService.getOne(Wrappers.<RdImplementationOrder>lambdaQuery().eq(RdImplementationOrder::getId, id));
        Assert.isNull(rdImplementationOrder, "找不到该实施工单信息，请联系管理员");
        RdResourceDir resDir = rdResourceDirService.getOne(new LambdaQueryWrapper<RdResourceDir>()
                .eq(rdImplementationOrder.getResUniqueCode() != null, RdResourceDir::getResCode, rdImplementationOrder.getResUniqueCode()));
        Assert.isNull(resDir, "无法获取资源信息，请联系管理员");
        if (orderOperate == 1) {
            // 实施完成
            RdResourceDirData rdResourceDirData = resourceDirDataService.getOne(new LambdaQueryWrapper<RdResourceDirData>()
                    .eq(RdResourceDirData::getResDirId, resDir.getId()));
            RdResDetailsApi rdResDetailsApi = rdResDetailsApiService.getOne(new LambdaQueryWrapper<RdResDetailsApi>()
                    .eq(RdResDetailsApi::getResDirId, resDir.getId()));
            // 服务接口类
            if (postResType == 1) {
                List<RdOrderApp> rdOrderAppList = rdOrderAppService.list(new LambdaQueryWrapper<RdOrderApp>()
                        .eq(RdOrderApp::getApplyNum, rdImplementationOrder.getApplyNum())
                        .isNull(RdOrderApp::getVersionNum));
                // Assert.isTrue(rdOrderAppList.isEmpty(), "请先配置您的自建系统信息！");
                if (rdResDetailsApi == null) {
                    return Response.error("实施未完成");
                } else {
                    if (rdResourceDirData != null) {
                        boolean removeResourceDate = resourceDirDataService.remove(new LambdaQueryWrapper<RdResourceDirData>()
                                .eq(RdResourceDirData::getResDirId, resDir.getId()));
                        List<RdResDataItem> rdResDataItemList = rdResDataItemService.list(new LambdaQueryWrapper<RdResDataItem>()
                                .eq(RdResDataItem::getOwnResId, resDir.getId()));
                        boolean removeItems = true;
                        if (!rdResDataItemList.isEmpty()) {
                            removeItems = rdResDataItemService.removeById(resDir.getId());
                        }
                        Assert.notTrue(removeResourceDate && removeItems, "实施状态修改操作失败，请联系管理员");
                    }
                }
                updateDir(postResType, resDir);
                // 更新实施工单的状态
                updateOrder(orderOperate, rdImplementationOrder, userId, userName, postResType);
                // 服务页面类，数据交换类
            } else if (postResType == 2 || postResType == 3) {
                if (rdResDetailsApi != null) {
                    boolean removeApi = rdResDetailsApiService.remove(new LambdaQueryWrapper<RdResDetailsApi>()
                            .eq(RdResDetailsApi::getResDirId, resDir.getId()));
                    Assert.notTrue(removeApi, "实施状态修改操作失败，请联系管理员");
                }
                updateDir(postResType, resDir);
                // 更新实施工单的状态
                updateOrder(orderOperate, rdImplementationOrder, userId, userName, postResType);
            }

        } else if (orderOperate == 2) {
            // 取消实施
            String cancelReason = (String) map.get("cancelReason");
            Assert.isNull(cancelReason, "取消实施请输入取消理由");
            Boolean withdraw = approvalAllApi.withdraw(rdImplementationOrder.getApplyNum(), userId, date, 0);
            Assert.notTrue(withdraw, "取消实施操作失败，申请单撤回失败");
            // 取消理由加入数据库
            boolean updateCancelReason = rdImplementationOrderService.update(new LambdaUpdateWrapper<RdImplementationOrder>()
                    .eq(RdImplementationOrder::getId, id)
                    .set(RdImplementationOrder::getCancelReason, cancelReason));
            Assert.notTrue(updateCancelReason, "添加取消实施理由失败，请联系管理员");
            // 更新实施工单的状态
            updateOrder(orderOperate, rdImplementationOrder, userId, userName, postResType);
        }
        return Response.success();
    }




    private void updateDir(Integer postResType, RdResourceDir resDir) throws BizException {
        boolean updateResource = rdResourceDirService.update(new LambdaUpdateWrapper<RdResourceDir>()
                .eq(resDir.getId() != null, RdResourceDir::getId, resDir.getId())
                .set(RdResourceDir::getCollectionSituation, 1)
                .set(RdResourceDir::getIsRelease, 0)
                .set(RdResourceDir::getResType, postResType));
        Assert.notTrue(updateResource, "资源状态修改失败，请联系管理员");
    }

    /**
     * 更新实施工单状态
     *
     * @param orderOperate
     * @param rdImplementationOrder
     * @throws BizException
     */
    private void updateOrder(Integer orderOperate, RdImplementationOrder rdImplementationOrder, Integer userId, String userName, Integer resType) throws BizException {
        boolean updateOrder = rdImplementationOrderService.update(new LambdaUpdateWrapper<RdImplementationOrder>()
                .eq(rdImplementationOrder.getId() != null, RdImplementationOrder::getId, rdImplementationOrder.getId())
                .set(RdImplementationOrder::getImplementationState, orderOperate)
                .set(RdImplementationOrder::getFinishUserid, userId)
                .set(RdImplementationOrder::getFinishUsername, userName)
                .set(RdImplementationOrder::getResType, resType)
        );
        Assert.notTrue(updateOrder, "实施工单操作失败，请联系管理员");
    }

}
